﻿using ProtoBuf;
using ProtoBuf.Meta;
using System.IO;

/// <summary>
/// 序列化帮助类
/// </summary>
public class PBSerializer
{

    public static T Clone<T>(T data)
    {
        byte[] buffer = NSerialize<T>(data);
        return NDeserialize<T>(buffer);
    }


    /// <summary>
    /// 序列化pb数据
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="t"></param>
    /// <returns></returns>
    public static byte[] NSerialize<T>(T t)
    {
        byte[] buffer = null;

        using (MemoryStream m = new MemoryStream())
        {
            Serializer.Serialize<T>(m, t);

            m.Position = 0;
            int length = (int)m.Length;
            buffer = new byte[length];
            m.Read(buffer, 0, length);
        }

        return buffer;
    }


    ///// <summary>
    ///// 发送网络消息
    ///// </summary>
    ///// <typeparam name="T"></typeparam>
    ///// <param name="cmd"></param>
    ///// <param name="t"></param>
    //public static void SendNetMsg<T>(short cmd, T t)
    //{
    //    OrderBody ob = new OrderBody();
    //    ob.SetMsgHead(0, cmd);
    //    ob.SetMsgBody();
    //    byte[] bytes = PBSerializer.NSerialize<T>(t);
    //    ob.byteBuffer.WriteProto(bytes);
    //    ServerConnect.Instance.SendMsgWithData(cmd, ob.byteBuffer);
    //}


    ///// <summary>
    ///// 发送网络消息--只发消息码
    ///// </summary>
    ///// <typeparam name="T"></typeparam>
    ///// <param name="cmd"></param>
    ///// <param name="t"></param>
    //public static void SendNetMsg(short cmd)
    //{
    //    OrderBody ob = new OrderBody();
    //    ob.SetMsgHead(0, cmd);
    //    ob.SetMsgBody();
    //    ServerConnect.Instance.SendMsgWithData(cmd, ob.byteBuffer);
    //}



    public static byte[] NSerialize(object t)
    {
        byte[] buffer = null;

        using (MemoryStream m = new MemoryStream())
        {
            if (t != null)
            {
                RuntimeTypeModel.Default.Serialize(m, t);
            }

            m.Position = 0;
            int length = (int)m.Length;
            buffer = new byte[length];
            m.Read(buffer, 0, length);
        }

        return buffer;
    }


    public static int NSerialize(object t, byte[] buffer)
    {
        using (MemoryStream m = new MemoryStream())
        {
            if (t != null)
            {
                RuntimeTypeModel.Default.Serialize(m, t);
            }

            m.Position = 0;
            int length = (int)m.Length;
            m.Read(buffer, 0, length);
            return length;
        }
        return 0;
    }



    ///// <summary>
    ///// 反序列化pb数据
    ///// </summary>
    ///// <typeparam name="T"></typeparam>
    ///// <param name="buffer"></param>
    ///// <returns></returns>
    //public static T NDeserializeByBuffer<T>(ByteBuffer buffer)
    //{
    //    T t = default(T);
    //    byte[] bytes = buffer.ReadProto();
    //    t = NDeserialize<T>(bytes);
    //    return t;
    //}


    /// <summary>
    /// 反序列化pb数据
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="buffer"></param>
    /// <returns></returns>
    public static T NDeserialize<T>(byte[] buffer)
    {
        T t = default(T);
        using (MemoryStream m = new MemoryStream(buffer))
        {
            t = Serializer.Deserialize<T>(m);
        }
        return t;
    }

    public static object NDeserialize(byte[] buffer, System.Type type)
    {
        object t = null;
        using (MemoryStream m = new MemoryStream(buffer))
        {
            t = RuntimeTypeModel.Default.Deserialize(m, null, type);
        }
        return t;
    }

    public static object NDeserialize(byte[] buffer, int len, System.Type type)
    {
        object t = null;
        using (MemoryStream m = new MemoryStream(buffer))
        {
            t = RuntimeTypeModel.Default.Deserialize(m, null, type, len);
        }
        return t;
    }


    public static T NDeserialize<T>(Stream stream)
    {
        T t = default(T);
        t = Serializer.Deserialize<T>(stream);
        return t;
    }
}
